package model

import (
	"common/helper"
	"database/sql"
	"errors"
	"fmt"
	g "github.com/doug-martin/goqu/v9"
	"github.com/doug-martin/goqu/v9/exp"
	"github.com/shopspring/decimal"
	"strconv"
	"strings"
	"time"
)

type tblReportUser struct {
	Id                     string  `json:"id" db:"id" cbor:"id"`
	Ty                     int     `json:"ty" db:"ty" cbor:"ty"`
	ReportTime             int64   `json:"report_time" db:"report_time" cbor:"report_time"`
	Uid                    string  `json:"uid" db:"uid" cbor:"uid"`
	TotalCommissions       float64 `json:"total_commissions" db:"total_commissions" cbor:"total_commissions"`                         //历史总佣金
	WaitCommissions        float64 `json:"wait_commissions" db:"wait_commissions" cbor:"wait_commissions"`                            //待结算佣金
	TotalTeamNum           int64   `json:"total_team_num" db:"total_team_num" cbor:"total_team_num"`                                  //团队总人数
	DepositWithdrawDiff    float64 `json:"deposit_withdraw_diff" db:"deposit_withdraw_diff" cbor:"deposit_withdraw_diff"`             //团队存取查
	DirectPushNum          int64   `json:"direct_push_num" db:"direct_push_num" cbor:"direct_push_num"`                               //直推人数
	DirectPushDepositNum   int64   `json:"direct_push_deposit_num" db:"direct_push_deposit_num" cbor:"direct_push_deposit_num"`       //直推充值人数
	DirectPushFdBonus      float64 `json:"direct_push_fd_bonus" db:"direct_push_fd_bonus" cbor:"direct_push_fd_bonus"`                //直推首充奖励
	DirectPushDeposit      float64 `json:"direct_push_deposit" db:"direct_push_deposit" cbor:"direct_push_deposit"`                   //直推充值
	DirectPushFlow         float64 `json:"direct_push_flow" db:"direct_push_flow" cbor:"direct_push_flow"`                            //直推流水
	DirectPushFlowBonus    float64 `json:"direct_push_flow_bonus" db:"direct_push_flow_bonus" cbor:"direct_push_flow_bonus"`          //直推流水奖励
	DirectPushDwDiff       float64 `json:"direct_push_dw_diff" db:"direct_push_dw_diff" cbor:"direct_push_dw_diff"`                   //直推充提差
	DirectPushWaitFlow     float64 `json:"direct_push_wait_flow" db:"direct_push_wait_flow" cbor:"direct_push_wait_flow"`             //待结算直推流水
	DirectPushWaitBonus    float64 `json:"direct_push_wait_bonus" db:"direct_push_wait_bonus" cbor:"direct_push_wait_bonus"`          //待结算直推流水奖励
	LvlSecondNum           int64   `json:"lvl_second_num" db:"lvl_second_num" cbor:"lvl_second_num"`                                  //二级人数
	LvlSecondDepositNum    int64   `json:"lvl_second_deposit_num" db:"lvl_second_deposit_num" cbor:"lvl_second_deposit_num"`          //二级充值人数
	LvlSecondDepositAmount float64 `json:"lvl_second_deposit_amount" db:"lvl_second_deposit_amount" cbor:"lvl_second_deposit_amount"` //二级充值金额
	LvlSecondFlow          float64 `json:"lvl_second_flow" db:"lvl_second_flow" cbor:"lvl_second_flow"`                               //二级流水
	LvlSecondFlowBonus     float64 `json:"lvl_second_flow_bonus" db:"lvl_second_flow_bonus" cbor:"lvl_second_flow_bonus"`             //二级流水奖励
	LvlSecondWaitFlow      float64 `json:"lvl_second_wait_flow" db:"lvl_second_wait_flow" cbor:"lvl_second_wait_flow"`                //二级待结算流水
	LvlSecondWaitBonus     float64 `json:"lvl_second_wait_bonus" db:"lvl_second_wait_bonus" cbor:"lvl_second_wait_bonus"`             //二级待结算流水奖励
	LvlSecondDwDiff        float64 `json:"lvl_second_dw_diff" db:"lvl_second_dw_diff" cbor:"lvl_second_dw_diff"`                      //二级充提差
	LvlThreeNum            int64   `json:"lvl_three_num" db:"lvl_three_num" cbor:"lvl_three_num"`                                     //三级人数
	LvlThreeDepositNum     int64   `json:"lvl_three_deposit_num" db:"lvl_three_deposit_num" cbor:"lvl_three_deposit_num"`             //三级充值人数
	LvlThreeDepositAmount  float64 `json:"lvl_three_deposit_amount" db:"lvl_three_deposit_amount" cbor:"lvl_three_deposit_amount"`    //三级充值金额
	LvlThreeFlow           float64 `json:"lvl_three_flow" db:"lvl_three_flow" cbor:"lvl_three_flow"`                                  //三级流水
	LvlThreeFlowBonus      float64 `json:"lvl_three_flow_bonus" db:"lvl_three_flow_bonus" cbor:"lvl_three_flow_bonus"`                //三级流水奖励
	LvlThreeWaitFlow       float64 `json:"lvl_three_wait_flow" db:"lvl_three_wait_flow" cbor:"lvl_three_wait_flow"`                   //三级待结算流水
	LvlThreeWaitBonus      float64 `json:"lvl_three_wait_bonus" db:"lvl_three_wait_bonus" cbor:"lvl_three_wait_bonus"`                //三级待结算流水奖励
	LvlThreeDwDiff         float64 `json:"lvl_three_dw_diff" db:"lvl_three_dw_diff" cbor:"lvl_three_dw_diff"`                         //三级充提差
	WithdrawAmount         float64 `json:"withdraw_amount" db:"withdraw_amount" cbor:"withdraw_amount"`                               //提现金额
	Username               string  `json:"username" db:"username" cbor:"username"`                                                    //用户名
	CreatedAt              uint32  `json:"created_at" db:"created_at" cbor:"created_at"`                                              //注册时间
	CreatedIp              string  `json:"created_ip" db:"created_ip" cbor:"created_ip"`                                              //注册ip
}

type reportUserSqlNull struct {
	Id                     string          `json:"id" db:"id" cbor:"id"`
	Ty                     int             `json:"ty" db:"ty" cbor:"ty"`
	ReportTime             int64           `json:"report_time" db:"report_time" cbor:"report_time"`
	Uid                    string          `json:"uid" db:"uid" cbor:"uid"`
	TotalCommissions       sql.NullFloat64 `json:"total_commissions" db:"total_commissions" cbor:"total_commissions"`                         //历史总佣金
	WaitCommissions        sql.NullFloat64 `json:"wait_commissions" db:"wait_commissions" cbor:"wait_commissions"`                            //待结算佣金
	TotalTeamNum           sql.NullInt64   `json:"total_team_num" db:"total_team_num" cbor:"total_team_num"`                                  //团队总人数
	DepositWithdrawDiff    sql.NullFloat64 `json:"deposit_withdraw_diff" db:"deposit_withdraw_diff" cbor:"deposit_withdraw_diff"`             //团队存取查
	DirectPushNum          sql.NullInt64   `json:"direct_push_num" db:"direct_push_num" cbor:"direct_push_num"`                               //直推人数
	DirectPushDepositNum   sql.NullInt64   `json:"direct_push_deposit_num" db:"direct_push_deposit_num" cbor:"direct_push_deposit_num"`       //直推充值人数
	DirectPushFdBonus      sql.NullFloat64 `json:"direct_push_fd_bonus" db:"direct_push_fd_bonus" cbor:"direct_push_fd_bonus"`                //直推首充奖励
	DirectPushDeposit      sql.NullFloat64 `json:"direct_push_deposit" db:"direct_push_deposit" cbor:"direct_push_deposit"`                   //直推充值
	DirectPushFlow         sql.NullFloat64 `json:"direct_push_flow" db:"direct_push_flow" cbor:"direct_push_flow"`                            //直推流水
	DirectPushFlowBonus    sql.NullFloat64 `json:"direct_push_flow_bonus" db:"direct_push_flow_bonus" cbor:"direct_push_flow_bonus"`          //直推流水奖励
	DirectPushDwDiff       sql.NullFloat64 `json:"direct_push_dw_diff" db:"direct_push_dw_diff" cbor:"direct_push_dw_diff"`                   //直推充提差
	DirectPushWaitFlow     sql.NullFloat64 `json:"direct_push_wait_flow" db:"direct_push_wait_flow" cbor:"direct_push_wait_flow"`             //待结算直推流水
	DirectPushWaitBonus    sql.NullFloat64 `json:"direct_push_wait_bonus" db:"direct_push_wait_bonus" cbor:"direct_push_wait_bonus"`          //待结算直推流水奖励
	LvlSecondNum           sql.NullInt64   `json:"lvl_second_num" db:"lvl_second_num" cbor:"lvl_second_num"`                                  //二级人数
	LvlSecondDepositNum    sql.NullInt64   `json:"lvl_second_deposit_num" db:"lvl_second_deposit_num" cbor:"lvl_second_deposit_num"`          //二级充值人数
	LvlSecondDepositAmount sql.NullFloat64 `json:"lvl_second_deposit_amount" db:"lvl_second_deposit_amount" cbor:"lvl_second_deposit_amount"` //二级充值金额
	LvlSecondFlow          sql.NullFloat64 `json:"lvl_second_flow" db:"lvl_second_flow" cbor:"lvl_second_flow"`                               //二级流水
	LvlSecondFlowBonus     sql.NullFloat64 `json:"lvl_second_flow_bonus" db:"lvl_second_flow_bonus" cbor:"lvl_second_flow_bonus"`             //二级流水奖励
	LvlSecondWaitFlow      sql.NullFloat64 `json:"lvl_second_wait_flow" db:"lvl_second_wait_flow" cbor:"lvl_second_wait_flow"`                //二级待结算流水
	LvlSecondWaitBonus     sql.NullFloat64 `json:"lvl_second_wait_bonus" db:"lvl_second_wait_bonus" cbor:"lvl_second_wait_bonus"`             //二级待结算流水奖励
	LvlSecondDwDiff        sql.NullFloat64 `json:"lvl_second_dw_diff" db:"lvl_second_dw_diff" cbor:"lvl_second_dw_diff"`                      //二级充提差
	LvlThreeNum            sql.NullInt64   `json:"lvl_three_num" db:"lvl_three_num" cbor:"lvl_three_num"`                                     //三级人数
	LvlThreeDepositNum     sql.NullInt64   `json:"lvl_three_deposit_num" db:"lvl_three_deposit_num" cbor:"lvl_three_deposit_num"`             //三级充值人数
	LvlThreeDepositAmount  sql.NullFloat64 `json:"lvl_three_deposit_amount" db:"lvl_three_deposit_amount" cbor:"lvl_three_deposit_amount"`    //三级充值金额
	LvlThreeFlow           sql.NullFloat64 `json:"lvl_three_flow" db:"lvl_three_flow" cbor:"lvl_three_flow"`                                  //三级流水
	LvlThreeFlowBonus      sql.NullFloat64 `json:"lvl_three_flow_bonus" db:"lvl_three_flow_bonus" cbor:"lvl_three_flow_bonus"`                //三级流水奖励
	LvlThreeWaitFlow       sql.NullFloat64 `json:"lvl_three_wait_flow" db:"lvl_three_wait_flow" cbor:"lvl_three_wait_flow"`                   //三级待结算流水
	LvlThreeWaitBonus      sql.NullFloat64 `json:"lvl_three_wait_bonus" db:"lvl_three_wait_bonus" cbor:"lvl_three_wait_bonus"`                //三级待结算流水奖励
	LvlThreeDwDiff         sql.NullFloat64 `json:"lvl_three_dw_diff" db:"lvl_three_dw_diff" cbor:"lvl_three_dw_diff"`                         //三级充提差
	WithdrawAmount         sql.NullFloat64 `json:"withdraw_amount" db:"withdraw_amount" cbor:"withdraw_amount"`                               //提现金额
	Username               string          `json:"username" db:"username" cbor:"username"`                                                    //用户名
	CreatedAt              uint32          `json:"created_at" db:"created_at" cbor:"created_at"`                                              //注册时间
	CreatedIp              string          `json:"created_ip" db:"created_ip" cbor:"created_ip"`                                              //注册ip
}

type tblReportGame struct {
	ReportTime          string `db:"report_time" json:"report_time" cbor:"report_time"`
	ID                  string `db:"id" json:"id" cbor:"id"`
	ApiType             string `db:"api_type" json:"api_type" cbor:"api_type"`
	MemCount            int    `db:"mem_count" json:"mem_count" cbor:"mem_count"`
	BetCount            int    `db:"bet_count" json:"bet_count" cbor:"bet_count"`
	BetAmount           string `db:"bet_amount" json:"bet_amount" cbor:"bet_amount"`
	RebateAmount        string `db:"rebate_amount" json:"rebate_amount" cbor:"rebate_amount"`
	ValidBetAmount      string `db:"valid_bet_amount" json:"valid_bet_amount" cbor:"valid_bet_amount"`
	CompanyNetAmount    string `db:"company_net_amount" json:"company_net_amount" cbor:"company_net_amount"`
	AvgBetAmount        string `db:"avg_bet_amount" json:"avg_bet_amount" cbor:"avg_bet_amount"`
	AvgValidBetAmount   string `db:"avg_valid_bet_amount" json:"avg_valid_bet_amount" cbor:"avg_valid_bet_amount"`
	AvgCompanyNetAmount string `db:"avg_company_net_amount" json:"avg_company_net_amount" cbor:"avg_company_net_amount"`
	Presettle           string `db:"presettle" json:"presettle" cbor:"presettle"`
	ProfitRate          string `db:"profit_rate" json:"profit_rate" cbor:"profit_rate"`
	Uids                string `json:"uids" db:"uids"`
}

type tblReportPlatform struct {
	Id                    string  `json:"id" db:"id" cbor:"id"`
	ReportTime            int64   `json:"report_time" db:"report_time" cbor:"report_time"`
	ReportType            int     `json:"report_type" db:"report_type" cbor:"report_type"`
	ReportMonth           int64   `json:"report_month" db:"report_month" cbor:"report_month"`
	RegistCount           int64   `json:"regist_count" db:"regist_count" cbor:"regist_count"`
	ActiveCount           int64   `json:"active_count" db:"active_count" cbor:"active_count"`
	EfficientActiveCount  int64   `json:"efficient_active_count" db:"efficient_active_count" cbor:"efficient_active_count"`
	FirstDepositCount     int64   `json:"first_deposit_count" db:"first_deposit_count" cbor:"first_deposit_count"`
	SecondDepositCount    int64   `json:"second_deposit_count" db:"second_deposit_count" cbor:"second_deposit_count"`
	ThirdDepositCount     int64   `json:"third_deposit_count" db:"third_deposit_count" cbor:"third_deposit_count"`
	DepositCount          int64   `json:"deposit_count" db:"deposit_count" cbor:"deposit_count"`
	WithdrawalCount       int64   `json:"withdrawal_count" db:"withdrawal_count" cbor:"withdrawal_count"`
	ConversionRate        float64 `json:"conversion_rate" db:"conversion_rate" cbor:"conversion_rate"`
	FirstDepositAmount    float64 `json:"first_deposit_amount" db:"first_deposit_amount" cbor:"first_deposit_amount"`
	SecondDepositAmount   float64 `json:"second_deposit_amount" db:"second_deposit_amount" cbor:"second_deposit_amount"`
	ThirdDepositAmount    float64 `json:"third_deposit_amount" db:"third_deposit_amount" cbor:"third_deposit_amount"`
	AvgFirstDepositAmount float64 `json:"avg_first_deposit_amount" db:"avg_first_deposit_amount" cbor:"avg_first_deposit_amount"`
	DepositMemCount       int64   `json:"deposit_mem_count" db:"deposit_mem_count" cbor:"deposit_mem_count"`
	WithdrawalMemCount    int64   `json:"withdrawal_mem_count" db:"withdrawal_mem_count" cbor:"withdrawal_mem_count"`
	DepositAmount         float64 `json:"deposit_amount" db:"deposit_amount" cbor:"deposit_amount"`
	WithdrawalAmount      float64 `json:"withdrawal_amount" db:"withdrawal_amount" cbor:"withdrawal_amount"`
	DepositWithdrawalSub  float64 `json:"deposit_withdrawal_sub" db:"deposit_withdrawal_sub" cbor:"deposit_withdrawal_sub"`
	DepositWithdrawalRate float64 `json:"deposit_withdrawal_rate" db:"deposit_withdrawal_rate" cbor:"deposit_withdrawal_rate"`
	BetMemCount           int64   `json:"bet_mem_count" db:"bet_mem_count" cbor:"bet_mem_count"`
	BetNumCount           int64   `json:"bet_num_count" db:"bet_num_count" cbor:"bet_num_count"`
	BetAmount             float64 `json:"bet_amount" db:"bet_amount" cbor:"bet_amount"`
	ValidBetAmount        float64 `json:"valid_bet_amount" db:"valid_bet_amount" cbor:"valid_bet_amount"`
	CompanyNetAmount      float64 `json:"company_net_amount" db:"company_net_amount" cbor:"company_net_amount"`
	AvgCompanyNetAmount   float64 `json:"avg_company_net_amount" db:"avg_company_net_amount" cbor:"avg_company_net_amount"`
	ProfitAmount          float64 `json:"profit_amount" db:"profit_amount" cbor:"profit_amount"`
	Presettle             float64 `json:"presettle" db:"presettle" cbor:"presettle"`
	CompanyRevenue        float64 `json:"company_revenue" db:"company_revenue" cbor:"company_revenue"`
	Uids                  string  `json:"uids" db:"uids"`
}

type reportPlatformSqlNull struct {
	Id                    string          `json:"id" db:"id" cbor:"id"`
	Uids                  string          `json:"uids" db:"uids"`
	ReportTime            int64           `json:"report_time" db:"report_time" cbor:"report_time"`
	ReportType            int             `json:"report_type" db:"report_type" cbor:"report_type"`
	ReportMonth           int64           `json:"report_month" db:"report_month" cbor:"report_month"`
	RegistCount           sql.NullInt64   `json:"regist_count" db:"regist_count" cbor:"regist_count"`
	ActiveCount           sql.NullInt64   `json:"active_count" db:"active_count" cbor:"active_count"`
	EfficientActiveCount  sql.NullInt64   `json:"efficient_active_count" db:"efficient_active_count" cbor:"efficient_active_count"`
	FirstDepositCount     sql.NullInt64   `json:"first_deposit_count" db:"first_deposit_count" cbor:"first_deposit_count"`
	SecondDepositCount    sql.NullInt64   `json:"second_deposit_count" db:"second_deposit_count" cbor:"second_deposit_count"`
	ThirdDepositCount     sql.NullInt64   `json:"third_deposit_count" db:"third_deposit_count" cbor:"third_deposit_count"`
	DepositCount          sql.NullInt64   `json:"deposit_count" db:"deposit_count" cbor:"deposit_count"`
	WithdrawalCount       sql.NullInt64   `json:"withdrawal_count" db:"withdrawal_count" cbor:"withdrawal_count"`
	ConversionRate        sql.NullFloat64 `json:"conversion_rate" db:"conversion_rate" cbor:"conversion_rate"`
	FirstDepositAmount    sql.NullFloat64 `json:"first_deposit_amount" db:"first_deposit_amount" cbor:"first_deposit_amount"`
	SecondDepositAmount   sql.NullFloat64 `json:"second_deposit_amount" db:"second_deposit_amount" cbor:"second_deposit_amount"`
	ThirdDepositAmount    sql.NullFloat64 `json:"third_deposit_amount" db:"third_deposit_amount" cbor:"third_deposit_amount"`
	AvgFirstDepositAmount sql.NullFloat64 `json:"avg_first_deposit_amount" db:"avg_first_deposit_amount" cbor:"avg_first_deposit_amount"`
	DepositMemCount       sql.NullInt64   `json:"deposit_mem_count" db:"deposit_mem_count" cbor:"deposit_mem_count"`
	WithdrawalMemCount    sql.NullInt64   `json:"withdrawal_mem_count" db:"withdrawal_mem_count" cbor:"withdrawal_mem_count"`
	DepositAmount         sql.NullFloat64 `json:"deposit_amount" db:"deposit_amount" cbor:"deposit_amount"`
	WithdrawalAmount      sql.NullFloat64 `json:"withdrawal_amount" db:"withdrawal_amount" cbor:"withdrawal_amount"`
	DepositWithdrawalSub  sql.NullFloat64 `json:"deposit_withdrawal_sub" db:"deposit_withdrawal_sub" cbor:"deposit_withdrawal_sub"`
	DepositWithdrawalRate sql.NullFloat64 `json:"deposit_withdrawal_rate" db:"deposit_withdrawal_rate" cbor:"deposit_withdrawal_rate"`
	BetMemCount           sql.NullInt64   `json:"bet_mem_count" db:"bet_mem_count" cbor:"bet_mem_count"`
	BetNumCount           sql.NullInt64   `json:"bet_num_count" db:"bet_num_count" cbor:"bet_num_count"`
	BetAmount             sql.NullFloat64 `json:"bet_amount" db:"bet_amount" cbor:"bet_amount"`
	ValidBetAmount        sql.NullFloat64 `json:"valid_bet_amount" db:"valid_bet_amount" cbor:"valid_bet_amount"`
	CompanyNetAmount      sql.NullFloat64 `json:"company_net_amount" db:"company_net_amount" cbor:"company_net_amount"`
	AvgCompanyNetAmount   sql.NullFloat64 `json:"avg_company_net_amount" db:"avg_company_net_amount" cbor:"avg_company_net_amount"`
	ProfitAmount          sql.NullFloat64 `json:"profit_amount" db:"profit_amount" cbor:"profit_amount"`
	Presettle             sql.NullFloat64 `json:"presettle" db:"presettle" cbor:"presettle"`
	CompanyRevenue        sql.NullFloat64 `json:"company_revenue" db:"company_revenue" cbor:"company_revenue"`
}

type TBetReport struct {
	Id                  string  `json:"id" db:"id"`
	ReportTime          int64   `json:"report_time" db:"report_time"`
	ReportType          int64   `json:"report_type" db:"report_type"`
	ApiType             int64   `json:"api_type" db:"api_type"`
	Prefix              string  `json:"prefix" db:"prefix"`
	MemCount            int64   `json:"mem_count" db:"mem_count"`
	BetCount            int64   `json:"bet_count" db:"bet_count"`
	BetAmount           float64 `json:"bet_amount" db:"bet_amount"`
	ValidBetAmount      float64 `json:"valid_bet_amount" db:"valid_bet_amount"`
	CompanyNetAmount    float64 `json:"company_net_amount" db:"company_net_amount"`
	AvgBetAmount        float64 `json:"avg_bet_amount" db:"avg_bet_amount"`
	AvgValidBetAmount   float64 `json:"avg_valid_bet_amount" db:"avg_valid_bet_amount"`
	AvgCompanyNetAmount float64 `json:"avg_company_net_amount" db:"avg_company_net_amount"`
	Presettle           float64 `json:"presettle" db:"presettle"`
	ProfitRate          float64 `json:"profit_rate" db:"profit_rate"`
	RebateAmount        float64 `json:"rebate_amount" db:"rebate_amount"`
	Uids                string  `json:"uids" db:"uids"`
}

type platformReportData struct {
	T int                 `cbor:"t" json:"total"`
	D []tblReportPlatform `cbor:"d" json:"d"`
}

type agencyReportData struct {
	T int             `cbor:"t" json:"total"`
	D []tblReportUser `cbor:"d" json:"d"`
	S int             `json:"s" cbor:"s"`
}

type GameReportData struct {
	D   []tblReportGame `json:"d"`
	T   int64           `json:"total"`
	S   int             `json:"s"`
	Agg tblReportGame   `json:"agg"`
}

type TDepositsRecord struct {
	DepositNum    sql.NullInt64   `db:"deposit_num" json:"deposit_num"`
	DepositAmount sql.NullFloat64 `db:"deposit_amount" json:"deposit_amount"`
	DepositCount  sql.NullInt64   `db:"deposit_count" json:"deposit_count"`
}

type TWithdrawRecord struct {
	WithdrawNum    sql.NullInt64   `db:"withdraw_num" json:"withdraw_num"`
	WithdrawAmount sql.NullFloat64 `db:"withdraw_amount" json:"withdraw_amount"`
	WithdrawCount  sql.NullInt64   `db:"withdraw_count" json:"withdraw_count"`
}

type TGameRecord struct {
	BetMemCount    sql.NullInt64   `json:"bet_mem_count" db:"bet_mem_count"`
	BetNumCount    sql.NullInt64   `json:"bet_num_count" db:"bet_num_count"`
	BetAmount      sql.NullFloat64 `json:"bet_amount" db:"bet_amount"`
	ValidBetAmount sql.NullFloat64 `json:"valid_bet_amount" db:"valid_bet_amount"`
	NetAmount      sql.NullFloat64 `json:"net_amount" db:"net_amount"`
	Presettle      sql.NullFloat64 `json:"presettle" db:"presettle"`
}

type TDepositInfo struct {
	ReportTime    string  `json:"report_time" db:"report_time"`
	DepositCount  int64   `json:"deposit_count" db:"deposit_count"`
	DepositAmount float64 `json:"deposit_amount" db:"deposit_amount"`
	Flags         int     `json:"flags" db:"flags"`
}

type TActiveData struct {
	ReportTime    string  `json:"report_time" db:"report_time"`
	Uid           string  `json:"uid" db:"uid"`
	DepositAmount float64 `json:"deposit_amount" db:"deposit_amount"`
	BetAmount     float64 `json:"bet_amount" db:"bet_amount"`
}

func UserReport(page, pageSize int, uid, userName, sStartTime, sEndTime string) (agencyReportData, error) {

	var (
		data      agencyReportData
		sqlData   []reportUserSqlNull
		startTime int64
	)
	data.S = pageSize
	if len(sStartTime) > 0 {
		t, err := helper.TimeToLoc(sStartTime, loc) // 秒级时间戳
		if err != nil {
			return data, err
		}
		startTime = t
	}
	var endTime int64
	if len(sEndTime) > 0 {
		t, err := helper.TimeToLoc(sEndTime, loc) // 秒级时间戳
		if err != nil {
			return data, err
		}
		endTime = t
	}
	ex := g.Ex{
		"report_time": g.Op{"between": exp.NewRangeVal(startTime, endTime)},
	}
	if userName != "" {
		ex["username"] = userName
	}
	if uid != "" {
		ex["uid"] = uid
	}
	t := dialect.From("tbl_report_user")
	if page >= 1 {
		query, _, _ := t.Select(g.COUNT(g.DISTINCT("uid"))).Where(ex).ToSQL()

		err := meta.MerchantDB.Get(&data.T, query)
		if err != nil && !errors.Is(err, sql.ErrNoRows) {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		}

		if errors.Is(err, sql.ErrNoRows) || data.T == 0 {
			return data, nil
		}
	}

	offset := (uint(page) - 1) * uint(pageSize)
	query, _, _ := t.Select(g.C(`uid`), g.MAX(`total_commissions`).As("total_commissions"), g.MAX(`wait_commissions`).As("wait_commissions"),
		g.MAX(`total_team_num`).As("total_team_num"), g.SUM(`deposit_withdraw_diff`).As("deposit_withdraw_diff"),
		g.SUM(`direct_push_num`).As("direct_push_num"), g.MAX(`direct_push_deposit_num`).As("direct_push_deposit_num"), g.SUM(`direct_push_fd_bonus`).As("direct_push_fd_bonus"),
		g.SUM(`direct_push_deposit`).As("direct_push_deposit"), g.SUM(`direct_push_flow`).As("direct_push_flow"), g.SUM(`direct_push_flow_bonus`).As("direct_push_flow_bonus"),
		g.SUM(`direct_push_dw_diff`).As("direct_push_dw_diff"), g.SUM(`direct_push_wait_flow`).As("direct_push_wait_flow"), g.SUM(`direct_push_wait_bonus`).As("direct_push_wait_bonus"),
		g.SUM(`lvl_second_num`).As("lvl_second_num"), g.SUM(`lvl_second_deposit_num`).As("lvl_second_deposit_num"), g.SUM(`lvl_second_deposit_amount`).As("lvl_second_deposit_amount"),
		g.SUM(`lvl_second_flow`).As("lvl_second_flow"), g.SUM(`lvl_second_flow_bonus`).As("lvl_second_flow_bonus"), g.SUM(`lvl_second_wait_flow`).As("lvl_second_wait_flow"),
		g.SUM(`lvl_second_wait_bonus`).As("lvl_second_wait_bonus"), g.SUM(`lvl_second_dw_diff`).As("lvl_second_dw_diff"), g.SUM(`lvl_three_num`).As("lvl_three_num"),
		g.MAX(`lvl_three_deposit_num`).As("lvl_three_deposit_num"), g.SUM(`lvl_three_deposit_amount`).As("lvl_three_deposit_amount"), g.SUM(`lvl_three_flow`).As("lvl_three_flow"),
		g.SUM(`lvl_three_flow_bonus`).As("lvl_three_flow_bonus"), g.SUM(`lvl_three_wait_flow`).As("lvl_three_wait_flow"), g.SUM(`lvl_three_wait_bonus`).As("lvl_three_wait_bonus"),
		g.SUM(`lvl_three_dw_diff`).As("lvl_three_dw_diff"), g.SUM(`withdraw_amount`).As("withdraw_amount")).Where(ex).GroupBy(g.C("uid")).Offset(offset).Limit(uint(pageSize)).Order(g.C(`uid`).Desc()).ToSQL()

	err := meta.MerchantDB.Select(&sqlData, query)
	if err != nil && err != sql.ErrNoRows {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	for _, v := range sqlData {
		mb, _ := MemberFindByUid(v.Uid)
		data.D = append(data.D, tblReportUser{
			Id:                     v.Id,
			Ty:                     v.Ty,
			ReportTime:             v.ReportTime,
			Uid:                    v.Uid,
			TotalCommissions:       v.TotalCommissions.Float64,       //历史总佣金
			WaitCommissions:        v.WaitCommissions.Float64,        //待结算佣金
			TotalTeamNum:           v.TotalTeamNum.Int64,             //团队总人数
			DepositWithdrawDiff:    v.DepositWithdrawDiff.Float64,    //团队存取查
			DirectPushNum:          v.DirectPushNum.Int64,            //直推人数
			DirectPushDepositNum:   v.DirectPushDepositNum.Int64,     //直推充值人数
			DirectPushFdBonus:      v.DirectPushFdBonus.Float64,      //直推首充奖励
			DirectPushDeposit:      v.DirectPushDeposit.Float64,      //直推充值
			DirectPushFlow:         v.DirectPushFlow.Float64,         //直推流水
			DirectPushFlowBonus:    v.DirectPushFlowBonus.Float64,    //直推流水奖励
			DirectPushDwDiff:       v.DirectPushDwDiff.Float64,       //直推充提差
			DirectPushWaitFlow:     v.DirectPushWaitFlow.Float64,     //待结算直推流水
			DirectPushWaitBonus:    v.DirectPushWaitBonus.Float64,    //待结算直推流水奖励
			LvlSecondNum:           v.LvlSecondNum.Int64,             //二级人数
			LvlSecondDepositNum:    v.LvlSecondDepositNum.Int64,      //二级充值人数
			LvlSecondDepositAmount: v.LvlSecondDepositAmount.Float64, //二级充值金额
			LvlSecondFlow:          v.LvlSecondFlow.Float64,          //二级流水
			LvlSecondFlowBonus:     v.LvlSecondFlowBonus.Float64,     //二级流水奖励
			LvlSecondWaitFlow:      v.LvlSecondWaitFlow.Float64,      //二级待结算流水
			LvlSecondWaitBonus:     v.LvlSecondWaitBonus.Float64,     //二级待结算流水奖励
			LvlSecondDwDiff:        v.LvlSecondDwDiff.Float64,        //二级充提差
			LvlThreeNum:            v.LvlThreeNum.Int64,              //三级人数
			LvlThreeDepositNum:     v.LvlThreeDepositNum.Int64,       //三级充值人数
			LvlThreeDepositAmount:  v.LvlThreeDepositAmount.Float64,  //三级充值金额
			LvlThreeFlow:           v.LvlThreeFlow.Float64,           //三级流水
			LvlThreeFlowBonus:      v.LvlThreeFlowBonus.Float64,      //三级流水奖励
			LvlThreeWaitFlow:       v.LvlThreeWaitFlow.Float64,       //三级待结算流水
			LvlThreeWaitBonus:      v.LvlThreeWaitBonus.Float64,      //三级待结算流水奖励
			LvlThreeDwDiff:         v.LvlThreeDwDiff.Float64,         //三级充提差
			WithdrawAmount:         v.WithdrawAmount.Float64,         //提现金额
			Username:               mb.Username,
			CreatedIp:              mb.CreatedIp,
			CreatedAt:              uint32(mb.CreatedAt),
		})
	}
	return data, nil
}

func MerchantUserReport(page, pageSize int, operatorId, uid, userName, sStartTime, sEndTime string) (agencyReportData, error) {

	var (
		data      agencyReportData
		sqlData   []reportUserSqlNull
		startTime int64
	)
	if len(sStartTime) > 0 {
		t, err := helper.TimeToLoc(sStartTime, loc) // 秒级时间戳
		if err != nil {
			return data, err
		}
		startTime = t
	}
	var endTime int64
	if len(sEndTime) > 0 {
		t, err := helper.TimeToLoc(sEndTime, loc) // 秒级时间戳
		if err != nil {
			return data, err
		}
		endTime = t
	}
	ex := g.Ex{
		"report_time": g.Op{"between": exp.NewRangeVal(startTime, endTime)},
	}
	uids := make([]string, 0)
	if userName != "" { // 用户名校验
		mb, err := MemberFindByUnameAndOpeId(userName, operatorId)
		if err != nil {
			return data, errors.New(helper.UsernameErr)
		}
		ex["username"] = userName
		ex["uid"] = mb.Uid
	} else {
		members, err := MemberFindByOperatorId(operatorId)
		if err != nil {
			return data, errors.New(helper.OperatorIdErr)
		}
		if len(members) > 0 {
			for _, val := range members {
				uids = append(uids, val.Uid)
			}
			ex["uid"] = uids
		}
	}
	if uid != "" {
		mb, err := MemberFindByUidAndOpeId(uid, operatorId)
		if err != nil {
			return data, errors.New(helper.OperatorIdErr)
		}
		ex["uid"] = mb.Uid
	}
	t := dialect.From("tbl_report_user")
	if page >= 1 {
		query, _, _ := t.Select(g.COUNT("uid")).Where(ex).ToSQL()

		err := meta.MerchantDB.Get(&data.T, query)
		if err != nil && !errors.Is(err, sql.ErrNoRows) {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		}

		if errors.Is(err, sql.ErrNoRows) || data.T == 0 {
			return data, nil
		}
	}

	offset := (uint(page) - 1) * uint(pageSize)
	query, _, _ := t.Select(g.C(`uid`), g.MAX(`total_commissions`).As("total_commissions"), g.MAX(`wait_commissions`).As("wait_commissions"),
		g.MAX(`total_team_num`).As("total_team_num"), g.SUM(`deposit_withdraw_diff`).As("deposit_withdraw_diff"),
		g.SUM(`direct_push_num`).As("direct_push_num"), g.MAX(`direct_push_deposit_num`).As("direct_push_deposit_num"), g.SUM(`direct_push_fd_bonus`).As("direct_push_fd_bonus"),
		g.SUM(`direct_push_deposit`).As("direct_push_deposit"), g.SUM(`direct_push_flow`).As("direct_push_flow"), g.SUM(`direct_push_flow_bonus`).As("direct_push_flow_bonus"),
		g.SUM(`direct_push_dw_diff`).As("direct_push_dw_diff"), g.SUM(`direct_push_wait_flow`).As("direct_push_wait_flow"), g.SUM(`direct_push_wait_bonus`).As("direct_push_wait_bonus"),
		g.SUM(`lvl_second_num`).As("lvl_second_num"), g.SUM(`lvl_second_deposit_num`).As("lvl_second_deposit_num"), g.SUM(`lvl_second_deposit_amount`).As("lvl_second_deposit_amount"),
		g.SUM(`lvl_second_flow`).As("lvl_second_flow"), g.SUM(`lvl_second_flow_bonus`).As("lvl_second_flow_bonus"), g.SUM(`lvl_second_wait_flow`).As("lvl_second_wait_flow"),
		g.SUM(`lvl_second_wait_bonus`).As("lvl_second_wait_bonus"), g.SUM(`lvl_second_dw_diff`).As("lvl_second_dw_diff"), g.SUM(`lvl_three_num`).As("lvl_three_num"),
		g.MAX(`lvl_three_deposit_num`).As("lvl_three_deposit_num"), g.SUM(`lvl_three_deposit_amount`).As("lvl_three_deposit_amount"), g.SUM(`lvl_three_flow`).As("lvl_three_flow"),
		g.SUM(`lvl_three_flow_bonus`).As("lvl_three_flow_bonus"), g.SUM(`lvl_three_wait_flow`).As("lvl_three_wait_flow"), g.SUM(`lvl_three_wait_bonus`).As("lvl_three_wait_bonus"),
		g.SUM(`lvl_three_dw_diff`).As("lvl_three_dw_diff"), g.SUM(`withdraw_amount`).As("withdraw_amount")).Where(ex).GroupBy(g.C("uid")).Offset(offset).Limit(uint(pageSize)).Order(g.MAX("total_team_num").Desc()).ToSQL()

	err := meta.MerchantDB.Select(&sqlData, query)
	if err != nil && err != sql.ErrNoRows {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	for _, v := range sqlData {
		mb, _ := MemberFindByUid(v.Uid)
		data.D = append(data.D, tblReportUser{
			Id:                     v.Id,
			Ty:                     v.Ty,
			ReportTime:             v.ReportTime,
			Uid:                    v.Uid,
			TotalCommissions:       v.TotalCommissions.Float64,       //历史总佣金
			WaitCommissions:        v.WaitCommissions.Float64,        //待结算佣金
			TotalTeamNum:           v.TotalTeamNum.Int64,             //团队总人数
			DepositWithdrawDiff:    v.DepositWithdrawDiff.Float64,    //团队存取查
			DirectPushNum:          v.DirectPushNum.Int64,            //直推人数
			DirectPushDepositNum:   v.DirectPushDepositNum.Int64,     //直推充值人数
			DirectPushFdBonus:      v.DirectPushFdBonus.Float64,      //直推首充奖励
			DirectPushDeposit:      v.DirectPushDeposit.Float64,      //直推充值
			DirectPushFlow:         v.DirectPushFlow.Float64,         //直推流水
			DirectPushFlowBonus:    v.DirectPushFlowBonus.Float64,    //直推流水奖励
			DirectPushDwDiff:       v.DirectPushDwDiff.Float64,       //直推充提差
			DirectPushWaitFlow:     v.DirectPushWaitFlow.Float64,     //待结算直推流水
			DirectPushWaitBonus:    v.DirectPushWaitBonus.Float64,    //待结算直推流水奖励
			LvlSecondNum:           v.LvlSecondNum.Int64,             //二级人数
			LvlSecondDepositNum:    v.LvlSecondDepositNum.Int64,      //二级充值人数
			LvlSecondDepositAmount: v.LvlSecondDepositAmount.Float64, //二级充值金额
			LvlSecondFlow:          v.LvlSecondFlow.Float64,          //二级流水
			LvlSecondFlowBonus:     v.LvlSecondFlowBonus.Float64,     //二级流水奖励
			LvlSecondWaitFlow:      v.LvlSecondWaitFlow.Float64,      //二级待结算流水
			LvlSecondWaitBonus:     v.LvlSecondWaitBonus.Float64,     //二级待结算流水奖励
			LvlSecondDwDiff:        v.LvlSecondDwDiff.Float64,        //二级充提差
			LvlThreeNum:            v.LvlThreeNum.Int64,              //三级人数
			LvlThreeDepositNum:     v.LvlThreeDepositNum.Int64,       //三级充值人数
			LvlThreeDepositAmount:  v.LvlThreeDepositAmount.Float64,  //三级充值金额
			LvlThreeFlow:           v.LvlThreeFlow.Float64,           //三级流水
			LvlThreeFlowBonus:      v.LvlThreeFlowBonus.Float64,      //三级流水奖励
			LvlThreeWaitFlow:       v.LvlThreeWaitFlow.Float64,       //三级待结算流水
			LvlThreeWaitBonus:      v.LvlThreeWaitBonus.Float64,      //三级待结算流水奖励
			LvlThreeDwDiff:         v.LvlThreeDwDiff.Float64,         //三级充提差
			WithdrawAmount:         v.WithdrawAmount.Float64,         //提现金额
			Username:               mb.Username,
			CreatedIp:              mb.CreatedIp,
			CreatedAt:              uint32(mb.CreatedAt),
		})
	}

	return data, nil
}

func BusinessUserReport(page, pageSize int, businessId, uid, userName, sStartTime, sEndTime string) (agencyReportData, error) {

	var (
		data      agencyReportData
		sqlData   []reportUserSqlNull
		startTime int64
	)
	if len(sStartTime) > 0 {
		t, err := helper.TimeToLoc(sStartTime, loc) // 秒级时间戳
		if err != nil {
			return data, err
		}
		startTime = t
	}
	var endTime int64
	if len(sEndTime) > 0 {
		t, err := helper.TimeToLoc(sEndTime, loc) // 秒级时间戳
		if err != nil {
			return data, err
		}
		endTime = t
	}
	ex := g.Ex{
		"report_time": g.Op{"between": exp.NewRangeVal(startTime, endTime)},
	}
	uids := make([]string, 0)
	if userName != "" { // 用户名校验
		mb, err := MemberFindByUnameAndProId(userName, businessId)
		if err != nil {
			return data, errors.New(helper.UsernameErr)
		}
		ex["username"] = userName
		ex["uid"] = mb.Uid
	} else {
		members, err := MemberFindByBusinessId(businessId)
		if err != nil {
			return data, errors.New(helper.BusinessIdErr)
		}
		if len(members) > 0 {
			for _, val := range members {
				uids = append(uids, val.Uid)
			}
			ex["uid"] = uids
		}
	}
	if uid != "" {
		mb, err := MemberFindByUidAndProId(uid, businessId)
		if err != nil {
			return data, errors.New(helper.BusinessIdErr)
		}
		ex["uid"] = mb.Uid
	}
	t := dialect.From("tbl_report_user")
	if page >= 1 {
		query, _, _ := t.Select(g.COUNT("uid")).Where(ex).ToSQL()

		err := meta.MerchantDB.Get(&data.T, query)
		if err != nil && !errors.Is(err, sql.ErrNoRows) {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		}

		if errors.Is(err, sql.ErrNoRows) || data.T == 0 {
			return data, nil
		}
	}

	offset := (uint(page) - 1) * uint(pageSize)
	query, _, _ := t.Select(g.C(`uid`), g.MAX(`total_commissions`).As("total_commissions"), g.MAX(`wait_commissions`).As("wait_commissions"),
		g.MAX(`total_team_num`).As("total_team_num"), g.SUM(`deposit_withdraw_diff`).As("deposit_withdraw_diff"),
		g.SUM(`direct_push_num`).As("direct_push_num"), g.MAX(`direct_push_deposit_num`).As("direct_push_deposit_num"), g.SUM(`direct_push_fd_bonus`).As("direct_push_fd_bonus"),
		g.SUM(`direct_push_deposit`).As("direct_push_deposit"), g.SUM(`direct_push_flow`).As("direct_push_flow"), g.SUM(`direct_push_flow_bonus`).As("direct_push_flow_bonus"),
		g.SUM(`direct_push_dw_diff`).As("direct_push_dw_diff"), g.SUM(`direct_push_wait_flow`).As("direct_push_wait_flow"), g.SUM(`direct_push_wait_bonus`).As("direct_push_wait_bonus"),
		g.SUM(`lvl_second_num`).As("lvl_second_num"), g.SUM(`lvl_second_deposit_num`).As("lvl_second_deposit_num"), g.SUM(`lvl_second_deposit_amount`).As("lvl_second_deposit_amount"),
		g.SUM(`lvl_second_flow`).As("lvl_second_flow"), g.SUM(`lvl_second_flow_bonus`).As("lvl_second_flow_bonus"), g.SUM(`lvl_second_wait_flow`).As("lvl_second_wait_flow"),
		g.SUM(`lvl_second_wait_bonus`).As("lvl_second_wait_bonus"), g.SUM(`lvl_second_dw_diff`).As("lvl_second_dw_diff"), g.SUM(`lvl_three_num`).As("lvl_three_num"),
		g.MAX(`lvl_three_deposit_num`).As("lvl_three_deposit_num"), g.SUM(`lvl_three_deposit_amount`).As("lvl_three_deposit_amount"), g.SUM(`lvl_three_flow`).As("lvl_three_flow"),
		g.SUM(`lvl_three_flow_bonus`).As("lvl_three_flow_bonus"), g.SUM(`lvl_three_wait_flow`).As("lvl_three_wait_flow"), g.SUM(`lvl_three_wait_bonus`).As("lvl_three_wait_bonus"),
		g.SUM(`lvl_three_dw_diff`).As("lvl_three_dw_diff"), g.SUM(`withdraw_amount`).As("withdraw_amount")).Where(ex).GroupBy(g.C("uid")).Offset(offset).Limit(uint(pageSize)).Order(g.MAX("total_team_num").Desc()).ToSQL()

	err := meta.MerchantDB.Select(&sqlData, query)
	if err != nil && err != sql.ErrNoRows {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	for _, v := range sqlData {
		mb, _ := MemberFindByUid(v.Uid)
		data.D = append(data.D, tblReportUser{
			Id:                     v.Id,
			Ty:                     v.Ty,
			ReportTime:             v.ReportTime,
			Uid:                    v.Uid,
			TotalCommissions:       v.TotalCommissions.Float64,       //历史总佣金
			WaitCommissions:        v.WaitCommissions.Float64,        //待结算佣金
			TotalTeamNum:           v.TotalTeamNum.Int64,             //团队总人数
			DepositWithdrawDiff:    v.DepositWithdrawDiff.Float64,    //团队存取查
			DirectPushNum:          v.DirectPushNum.Int64,            //直推人数
			DirectPushDepositNum:   v.DirectPushDepositNum.Int64,     //直推充值人数
			DirectPushFdBonus:      v.DirectPushFdBonus.Float64,      //直推首充奖励
			DirectPushDeposit:      v.DirectPushDeposit.Float64,      //直推充值
			DirectPushFlow:         v.DirectPushFlow.Float64,         //直推流水
			DirectPushFlowBonus:    v.DirectPushFlowBonus.Float64,    //直推流水奖励
			DirectPushDwDiff:       v.DirectPushDwDiff.Float64,       //直推充提差
			DirectPushWaitFlow:     v.DirectPushWaitFlow.Float64,     //待结算直推流水
			DirectPushWaitBonus:    v.DirectPushWaitBonus.Float64,    //待结算直推流水奖励
			LvlSecondNum:           v.LvlSecondNum.Int64,             //二级人数
			LvlSecondDepositNum:    v.LvlSecondDepositNum.Int64,      //二级充值人数
			LvlSecondDepositAmount: v.LvlSecondDepositAmount.Float64, //二级充值金额
			LvlSecondFlow:          v.LvlSecondFlow.Float64,          //二级流水
			LvlSecondFlowBonus:     v.LvlSecondFlowBonus.Float64,     //二级流水奖励
			LvlSecondWaitFlow:      v.LvlSecondWaitFlow.Float64,      //二级待结算流水
			LvlSecondWaitBonus:     v.LvlSecondWaitBonus.Float64,     //二级待结算流水奖励
			LvlSecondDwDiff:        v.LvlSecondDwDiff.Float64,        //二级充提差
			LvlThreeNum:            v.LvlThreeNum.Int64,              //三级人数
			LvlThreeDepositNum:     v.LvlThreeDepositNum.Int64,       //三级充值人数
			LvlThreeDepositAmount:  v.LvlThreeDepositAmount.Float64,  //三级充值金额
			LvlThreeFlow:           v.LvlThreeFlow.Float64,           //三级流水
			LvlThreeFlowBonus:      v.LvlThreeFlowBonus.Float64,      //三级流水奖励
			LvlThreeWaitFlow:       v.LvlThreeWaitFlow.Float64,       //三级待结算流水
			LvlThreeWaitBonus:      v.LvlThreeWaitBonus.Float64,      //三级待结算流水奖励
			LvlThreeDwDiff:         v.LvlThreeDwDiff.Float64,         //三级充提差
			WithdrawAmount:         v.WithdrawAmount.Float64,         //提现金额
			Username:               mb.Username,
			CreatedIp:              mb.CreatedIp,
			CreatedAt:              uint32(mb.CreatedAt),
		})
	}

	return data, nil
}

func PlatformReport(page, pageSize int, sStartTime, sEndTime string) (platformReportData, error) {

	var data platformReportData
	var startTime int64
	if len(sStartTime) > 0 {
		t, err := helper.TimeToLoc(sStartTime, loc) // 秒级时间戳
		if err != nil {
			return data, err
		}
		startTime = t
	}
	var endTime int64
	if len(sEndTime) > 0 {
		t, err := helper.TimeToLoc(sEndTime, loc) // 秒级时间戳
		if err != nil {
			return data, err
		}
		endTime = t
	}
	ex := g.Ex{
		"report_time": g.Op{"between": exp.NewRangeVal(startTime, endTime)},
	}
	t := dialect.From("tbl_report_platform")
	if page >= 1 {
		query, _, _ := t.Select(g.COUNT(1)).Where(ex).ToSQL()

		err := meta.MerchantDB.Get(&data.T, query)
		if err != nil {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		}

		if data.T == 0 {
			return data, nil
		}
	}

	offset := (uint(page) - 1) * uint(pageSize)
	query, _, _ := t.Select(colsReportPlatform...).Where(ex).Offset(offset).Limit(uint(pageSize)).Order(g.C("report_time").Desc()).ToSQL()

	err := meta.MerchantDB.Select(&data.D, query)
	if err != nil && err != sql.ErrNoRows {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	return data, nil
}

func GameReport(flag int, startTime, endTime, gameIds string, page, pageSize int) (GameReportData, error) {

	var data GameReportData

	startAt := helper.DaySST(startTime, loc).Unix()
	endAt := helper.DaySET(endTime, loc).Unix()
	if startAt > endAt {
		return data, errors.New(helper.QueryTimeRangeErr)
	}

	ex := g.Ex{
		"report_time": g.Op{"between": exp.NewRangeVal(startAt, endAt)},
	}

	if gameIds != "" {
		ex["api_type"] = strings.Split(gameIds, ",")
	}
	tableName := "tbl_report_game"
	ex["report_type"] = 2
	offset := (page - 1) * pageSize
	orderField := g.L("report_time")
	orderBy := orderField.Desc()

	query, _, _ := dialect.From(tableName).Select(g.COUNT("id")).Where(ex).ToSQL()
	err := meta.MerchantDB.Get(&data.T, query)
	if err != nil {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	if errors.Is(err, sql.ErrNoRows) || data.T == 0 {
		return data, nil
	}

	query, _, _ = dialect.From(tableName).Where(ex).Select(colsReportGame...).Order(orderBy).Offset(uint(offset)).Limit(uint(pageSize)).ToSQL()

	err = meta.MerchantDB.Select(&data.D, query)
	if err != nil {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	if data.T > 0 {
		aggQuery, _, _ := dialect.From(tableName).Select(
			g.SUM("mem_count").As("mem_count"),
			g.SUM("bet_count").As("bet_count"),
			g.SUM("bet_amount").As("bet_amount"),
			g.SUM("rebate_amount").As("rebate_amount"),
			g.SUM("valid_bet_amount").As("valid_bet_amount"),
			g.SUM("company_net_amount").As("company_net_amount"),
			g.SUM("presettle").As("presettle"),
			g.SUM("avg_bet_amount").As("avg_bet_amount"),
			g.SUM("avg_valid_bet_amount").As("avg_valid_bet_amount"),
			g.SUM("profit_rate").As("profit_rate"),
			g.SUM("avg_company_net_amount").As("avg_company_net_amount")).Where(ex).ToSQL()

		err = meta.MerchantDB.Get(&data.Agg, aggQuery)
		if err != nil {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		}
		cna, _ := decimal.NewFromString(data.Agg.CompanyNetAmount)
		pe, _ := decimal.NewFromString(data.Agg.Presettle)
		ba, _ := decimal.NewFromString(data.Agg.ValidBetAmount)
		if ba.Cmp(decimal.Zero) != 0 {
			data.Agg.ProfitRate = (cna.Add(pe)).Div(ba).StringFixed(4)
		}
	}

	data.D = reportGameFormat(data.D)
	return data, nil
}

func PlatformOverview(sStartTime, sEndTime string) (tblReportPlatform, error) {

	var (
		startTime int64
		data      = tblReportPlatform{}
		sqlData   = reportPlatformSqlNull{}
	)
	if len(sStartTime) > 0 {
		t, err := helper.TimeToLoc(sStartTime, loc) // 秒级时间戳
		if err != nil {
			return data, err
		}
		startTime = t
	}
	var endTime int64
	if len(sEndTime) > 0 {
		t, err := helper.TimeToLoc(sEndTime, loc) // 秒级时间戳
		if err != nil {
			return data, err
		}
		endTime = t
	}
	ex := g.Ex{
		"report_time": g.Op{"between": exp.NewRangeVal(startTime, endTime)},
	}
	query, _, _ := dialect.From("tbl_report_platform").Select(
		g.SUM("regist_count").As("regist_count"),
		g.SUM("active_count").As("active_count"),
		g.SUM("efficient_active_count").As("efficient_active_count"),
		g.SUM("first_deposit_count").As("first_deposit_count"),
		g.SUM("second_deposit_count").As("second_deposit_count"),
		g.SUM("third_deposit_count").As("third_deposit_count"),
		g.SUM("deposit_count").As("deposit_count"),
		g.SUM("withdrawal_count").As("withdrawal_count"),
		g.SUM("conversion_rate").As("conversion_rate"),
		g.SUM("first_deposit_amount").As("first_deposit_amount"),
		g.SUM("second_deposit_amount").As("second_deposit_amount"),
		g.SUM("third_deposit_amount").As("third_deposit_amount"),
		g.SUM("avg_first_deposit_amount").As("avg_first_deposit_amount"),
		g.SUM("deposit_mem_count").As("deposit_mem_count"),
		g.SUM("withdrawal_mem_count").As("withdrawal_mem_count"),
		g.SUM("deposit_amount").As("deposit_amount"),
		g.SUM("withdrawal_amount").As("withdrawal_amount"),
		g.SUM("deposit_withdrawal_sub").As("deposit_withdrawal_sub"),
		g.SUM("deposit_withdrawal_rate").As("deposit_withdrawal_rate"),
		g.SUM("bet_mem_count").As("bet_mem_count"),
		g.SUM("bet_num_count").As("bet_num_count"),
		g.SUM("bet_amount").As("bet_amount"),
		g.SUM("valid_bet_amount").As("valid_bet_amount"),
		g.SUM("company_net_amount").As("company_net_amount"),
		g.SUM("avg_company_net_amount").As("avg_company_net_amount"),
		g.SUM("deposit_withdrawal_rate").As("deposit_withdrawal_rate"),
		g.SUM("profit_amount").As("profit_amount"),
		g.SUM("presettle").As("presettle"),
		g.SUM("company_revenue").As("company_revenue")).Where(ex).ToSQL()

	err := meta.MerchantDB.Get(&sqlData, query)
	if err != nil {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	data = tblReportPlatform{
		Id:                    sqlData.Id,
		ReportTime:            sqlData.ReportTime,
		ReportType:            sqlData.ReportType,
		ReportMonth:           sqlData.ReportMonth,
		RegistCount:           sqlData.RegistCount.Int64,
		ActiveCount:           sqlData.ActiveCount.Int64,
		EfficientActiveCount:  sqlData.EfficientActiveCount.Int64,
		FirstDepositCount:     sqlData.FirstDepositCount.Int64,
		SecondDepositCount:    sqlData.SecondDepositCount.Int64,
		ThirdDepositCount:     sqlData.ThirdDepositCount.Int64,
		DepositCount:          sqlData.DepositCount.Int64,
		WithdrawalCount:       sqlData.WithdrawalCount.Int64,
		ConversionRate:        sqlData.ConversionRate.Float64,
		FirstDepositAmount:    sqlData.FirstDepositAmount.Float64,
		SecondDepositAmount:   sqlData.SecondDepositAmount.Float64,
		ThirdDepositAmount:    sqlData.ThirdDepositAmount.Float64,
		AvgFirstDepositAmount: sqlData.AvgFirstDepositAmount.Float64,
		DepositMemCount:       sqlData.DepositMemCount.Int64,
		WithdrawalMemCount:    sqlData.WithdrawalMemCount.Int64,
		DepositAmount:         sqlData.DepositAmount.Float64,
		WithdrawalAmount:      sqlData.WithdrawalAmount.Float64,
		DepositWithdrawalSub:  sqlData.DepositWithdrawalSub.Float64,
		DepositWithdrawalRate: sqlData.DepositWithdrawalRate.Float64,
		BetMemCount:           sqlData.BetMemCount.Int64,
		BetNumCount:           sqlData.BetNumCount.Int64,
		BetAmount:             sqlData.BetAmount.Float64,
		ValidBetAmount:        sqlData.ValidBetAmount.Float64,
		CompanyNetAmount:      sqlData.CompanyNetAmount.Float64,
		AvgCompanyNetAmount:   sqlData.AvgCompanyNetAmount.Float64,
		ProfitAmount:          sqlData.ProfitAmount.Float64,
		Presettle:             sqlData.Presettle.Float64,
		CompanyRevenue:        sqlData.CompanyRevenue.Float64,
	}

	return data, nil
}

func reportGameFormat(data []tblReportGame) []tblReportGame {

	for k, v := range data {

		data[k].ReportTime = parseDay(v.ReportTime)

		val, _ := decimal.NewFromString(v.BetAmount)
		data[k].BetAmount = val.StringFixed(2)

		ValidBetAmount, _ := decimal.NewFromString(v.ValidBetAmount)
		data[k].ValidBetAmount = ValidBetAmount.StringFixed(2)

		CompanyNetAmount, _ := decimal.NewFromString(v.CompanyNetAmount)
		data[k].CompanyNetAmount = CompanyNetAmount.StringFixed(2)

		Presettle, _ := decimal.NewFromString(v.Presettle)
		data[k].Presettle = Presettle.StringFixed(2)

		RebateAmount, _ := decimal.NewFromString(v.RebateAmount)
		data[k].RebateAmount = RebateAmount.StringFixed(2)

		if ValidBetAmount.Cmp(decimal.Zero) == 1 {
			data[k].ProfitRate = CompanyNetAmount.Add(Presettle).Div(ValidBetAmount).StringFixed(2)
		} else {
			data[k].ProfitRate = "0.00"
		}
	}

	return data
}

func parseDay(s string) string {

	t, _ := strconv.ParseInt(s, 10, 64)
	ts := time.Unix(t, 0).In(loc)

	return fmt.Sprintf("%s", ts.Format("2006-01-02"))
}

func MerchantGameReport(operatorId, startTime, endTime, gameIds string, page, pageSize int) (GameReportData, error) {
	var data GameReportData
	startAt := helper.DaySST(startTime, loc).Unix()
	endAt := helper.DaySET(endTime, loc).Unix()

	if startAt > endAt {
		return data, errors.New(helper.QueryTimeRangeErr)
	}
	uids := make([]string, 0)
	members, err := MemberFindByOperatorId(operatorId)
	if err != nil {
		return data, err
	}
	if len(members) > 0 {
		for _, val := range members {
			uids = append(uids, val.Uid)
		}
	}
	idArray := StringMontageComma(uids)
	if idArray != "" {
		gameReportDay(startAt, endAt, idArray)
		if err != nil {
			return data, err
		}
		ex := g.Ex{
			"report_time": g.Op{"between": exp.NewRangeVal(startAt, endAt)},
		}

		if gameIds != "" {
			ex["api_type"] = strings.Split(gameIds, ",")
		}
		ex["uids"] = idArray
		tableName := "tbl_report_game"
		ex["report_type"] = 2
		offset := (page - 1) * pageSize
		orderField := g.L("report_time")
		orderBy := orderField.Desc()

		query, _, _ := dialect.From(tableName).Select(g.COUNT("id")).Where(ex).ToSQL()
		err = meta.MerchantDB.Get(&data.T, query)

		if err != nil {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		}

		if errors.Is(err, sql.ErrNoRows) || data.T == 0 {
			return data, nil
		}

		query, _, _ = dialect.From(tableName).Where(ex).Select(colsReportGame...).Order(orderBy).Offset(uint(offset)).Limit(uint(pageSize)).ToSQL()

		err = meta.MerchantDB.Select(&data.D, query)
		if err != nil {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		}

		if data.T > 0 {
			aggQuery, _, _ := dialect.From(tableName).Select(
				g.SUM("mem_count").As("mem_count"),
				g.SUM("bet_count").As("bet_count"),
				g.SUM("bet_amount").As("bet_amount"),
				g.SUM("rebate_amount").As("rebate_amount"),
				g.SUM("valid_bet_amount").As("valid_bet_amount"),
				g.SUM("company_net_amount").As("company_net_amount"),
				g.SUM("presettle").As("presettle"),
				g.SUM("avg_bet_amount").As("avg_bet_amount"),
				g.SUM("avg_valid_bet_amount").As("avg_valid_bet_amount"),
				g.SUM("profit_rate").As("profit_rate"),
				g.SUM("avg_company_net_amount").As("avg_company_net_amount")).Where(ex).ToSQL()

			err = meta.MerchantDB.Get(&data.Agg, aggQuery)
			if err != nil {
				return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
			}
			cna, _ := decimal.NewFromString(data.Agg.CompanyNetAmount)
			pe, _ := decimal.NewFromString(data.Agg.Presettle)
			ba, _ := decimal.NewFromString(data.Agg.ValidBetAmount)
			if ba.Cmp(decimal.Zero) != 0 {
				data.Agg.ProfitRate = (cna.Add(pe)).Div(ba).StringFixed(4)
			}
		}

		data.D = reportGameFormat(data.D)
		return data, nil
	} else {
		return data, nil
	}

}

func MerchantPlatformReport(page, pageSize int, sStartTime, sEndTime, operatorId string) (platformReportData, error) {

	var data platformReportData
	var startTime int64
	if len(sStartTime) > 0 {
		t, err := helper.TimeToLoc(sStartTime, loc) // 秒级时间戳
		if err != nil {
			return data, err
		}
		startTime = t
	}
	var endTime int64
	if len(sEndTime) > 0 {
		t, err := helper.TimeToLoc(sEndTime, loc) // 秒级时间戳
		if err != nil {
			return data, err
		}
		endTime = t
	}
	uids := make([]string, 0)
	members, err := MemberFindByOperatorId(operatorId)
	if err != nil {
		return data, err
	}
	if len(members) > 0 {
		for _, val := range members {
			uids = append(uids, val.Uid)
		}
	}
	idArray := StringMontageComma(uids)
	if idArray != "" {
		platformReportJob(startTime, endTime, idArray)
		ex := g.Ex{
			"report_time": g.Op{"between": exp.NewRangeVal(startTime, endTime)},
		}
		ex["uids"] = idArray
		t := dialect.From("tbl_report_platform")
		if page >= 1 {
			query, _, _ := t.Select(g.COUNT(1)).Where(ex).ToSQL()

			err := meta.MerchantDB.Get(&data.T, query)
			if err != nil {
				return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
			}

			if data.T == 0 {
				return data, nil
			}
		}

		offset := (uint(page) - 1) * uint(pageSize)
		query, _, _ := t.Select(colsReportPlatform...).Where(ex).Offset(offset).Limit(uint(pageSize)).Order(g.C("report_time").Desc()).ToSQL()

		err = meta.MerchantDB.Select(&data.D, query)
		if err != nil && err != sql.ErrNoRows {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		}

		return data, nil
	} else {
		return data, nil
	}
}

func MerchantPlatformOverview(sStartTime, sEndTime, operatorId string) (tblReportPlatform, error) {

	var (
		startTime int64
		data      = tblReportPlatform{}
		sqlData   = reportPlatformSqlNull{}
	)
	if len(sStartTime) > 0 {
		t, err := helper.TimeToLoc(sStartTime, loc) // 秒级时间戳
		if err != nil {
			return data, err
		}
		startTime = t
	}
	var endTime int64
	if len(sEndTime) > 0 {
		t, err := helper.TimeToLoc(sEndTime, loc) // 秒级时间戳
		if err != nil {
			return data, err
		}
		endTime = t
	}
	uids := make([]string, 0)
	members, err := MemberFindByOperatorId(operatorId)
	if err != nil {
		return data, err
	}
	if len(members) > 0 {
		for _, val := range members {
			uids = append(uids, val.Uid)
		}
	}
	idArray := StringMontageComma(uids)

	if idArray != "" {
		platformReportJob(startTime, endTime, idArray)
		if err != nil {
			return data, err
		}
		ex := g.Ex{
			"report_time": g.Op{"between": exp.NewRangeVal(startTime, endTime)},
		}
		ex["uids"] = idArray
		query, _, _ := dialect.From("tbl_report_platform").Select(g.C("uids"),
			g.SUM("regist_count").As("regist_count"),
			g.SUM("active_count").As("active_count"),
			g.SUM("efficient_active_count").As("efficient_active_count"),
			g.SUM("first_deposit_count").As("first_deposit_count"),
			g.SUM("second_deposit_count").As("second_deposit_count"),
			g.SUM("third_deposit_count").As("third_deposit_count"),
			g.SUM("deposit_count").As("deposit_count"),
			g.SUM("withdrawal_count").As("withdrawal_count"),
			g.SUM("conversion_rate").As("conversion_rate"),
			g.SUM("first_deposit_amount").As("first_deposit_amount"),
			g.SUM("second_deposit_amount").As("second_deposit_amount"),
			g.SUM("third_deposit_amount").As("third_deposit_amount"),
			g.SUM("avg_first_deposit_amount").As("avg_first_deposit_amount"),
			g.SUM("deposit_mem_count").As("deposit_mem_count"),
			g.SUM("withdrawal_mem_count").As("withdrawal_mem_count"),
			g.SUM("deposit_amount").As("deposit_amount"),
			g.SUM("withdrawal_amount").As("withdrawal_amount"),
			g.SUM("deposit_withdrawal_sub").As("deposit_withdrawal_sub"),
			g.SUM("deposit_withdrawal_rate").As("deposit_withdrawal_rate"),
			g.SUM("bet_mem_count").As("bet_mem_count"),
			g.SUM("bet_num_count").As("bet_num_count"),
			g.SUM("bet_amount").As("bet_amount"),
			g.SUM("valid_bet_amount").As("valid_bet_amount"),
			g.SUM("company_net_amount").As("company_net_amount"),
			g.SUM("avg_company_net_amount").As("avg_company_net_amount"),
			g.SUM("deposit_withdrawal_rate").As("deposit_withdrawal_rate"),
			g.SUM("profit_amount").As("profit_amount"),
			g.SUM("presettle").As("presettle"),
			g.SUM("company_revenue").As("company_revenue")).Where(ex).ToSQL()

		err = meta.MerchantDB.Get(&sqlData, query)
		if err != nil {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		}

		data = tblReportPlatform{
			Id:                    sqlData.Id,
			Uids:                  sqlData.Uids,
			ReportTime:            sqlData.ReportTime,
			ReportType:            sqlData.ReportType,
			ReportMonth:           sqlData.ReportMonth,
			RegistCount:           sqlData.RegistCount.Int64,
			ActiveCount:           sqlData.ActiveCount.Int64,
			EfficientActiveCount:  sqlData.EfficientActiveCount.Int64,
			FirstDepositCount:     sqlData.FirstDepositCount.Int64,
			SecondDepositCount:    sqlData.SecondDepositCount.Int64,
			ThirdDepositCount:     sqlData.ThirdDepositCount.Int64,
			DepositCount:          sqlData.DepositCount.Int64,
			WithdrawalCount:       sqlData.WithdrawalCount.Int64,
			ConversionRate:        sqlData.ConversionRate.Float64,
			FirstDepositAmount:    sqlData.FirstDepositAmount.Float64,
			SecondDepositAmount:   sqlData.SecondDepositAmount.Float64,
			ThirdDepositAmount:    sqlData.ThirdDepositAmount.Float64,
			AvgFirstDepositAmount: sqlData.AvgFirstDepositAmount.Float64,
			DepositMemCount:       sqlData.DepositMemCount.Int64,
			WithdrawalMemCount:    sqlData.WithdrawalMemCount.Int64,
			DepositAmount:         sqlData.DepositAmount.Float64,
			WithdrawalAmount:      sqlData.WithdrawalAmount.Float64,
			DepositWithdrawalSub:  sqlData.DepositWithdrawalSub.Float64,
			DepositWithdrawalRate: sqlData.DepositWithdrawalRate.Float64,
			BetMemCount:           sqlData.BetMemCount.Int64,
			BetNumCount:           sqlData.BetNumCount.Int64,
			BetAmount:             sqlData.BetAmount.Float64,
			ValidBetAmount:        sqlData.ValidBetAmount.Float64,
			CompanyNetAmount:      sqlData.CompanyNetAmount.Float64,
			AvgCompanyNetAmount:   sqlData.AvgCompanyNetAmount.Float64,
			ProfitAmount:          sqlData.ProfitAmount.Float64,
			Presettle:             sqlData.Presettle.Float64,
			CompanyRevenue:        sqlData.CompanyRevenue.Float64,
		}

		return data, nil
	} else {
		return data, nil
	}
}

func BusinessGameReport(businessId, startTime, endTime, gameIds string, page, pageSize int) (GameReportData, error) {
	var data GameReportData
	startAt := helper.DaySST(startTime, loc).Unix()
	endAt := helper.DaySET(endTime, loc).Unix()

	if startAt > endAt {
		return data, errors.New(helper.QueryTimeRangeErr)
	}
	uids := make([]string, 0)
	members, err := MemberFindByBusinessId(businessId)
	if err != nil {
		return data, err
	}
	if len(members) > 0 {
		for _, val := range members {
			uids = append(uids, val.Uid)
		}
	}
	idArray := StringMontageComma(uids)

	if idArray != "" {
		gameReportDay(startAt, endAt, idArray)
		if err != nil {
			return data, err
		}
		ex := g.Ex{
			"report_time": g.Op{"between": exp.NewRangeVal(startAt, endAt)},
		}

		if gameIds != "" {
			ex["api_type"] = strings.Split(gameIds, ",")
		}
		ex["uids"] = idArray
		tableName := "tbl_report_game"
		ex["report_type"] = 2
		offset := (page - 1) * pageSize
		orderField := g.L("report_time")
		orderBy := orderField.Desc()

		query, _, _ := dialect.From(tableName).Select(g.COUNT("id")).Where(ex).ToSQL()
		err = meta.MerchantDB.Get(&data.T, query)

		if err != nil {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		}

		if errors.Is(err, sql.ErrNoRows) || data.T == 0 {
			return data, nil
		}

		query, _, _ = dialect.From(tableName).Where(ex).Select(colsReportGame...).Order(orderBy).Offset(uint(offset)).Limit(uint(pageSize)).ToSQL()

		err = meta.MerchantDB.Select(&data.D, query)
		if err != nil {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		}

		if data.T > 0 {
			aggQuery, _, _ := dialect.From(tableName).Select(
				g.SUM("mem_count").As("mem_count"),
				g.SUM("bet_count").As("bet_count"),
				g.SUM("bet_amount").As("bet_amount"),
				g.SUM("rebate_amount").As("rebate_amount"),
				g.SUM("valid_bet_amount").As("valid_bet_amount"),
				g.SUM("company_net_amount").As("company_net_amount"),
				g.SUM("presettle").As("presettle"),
				g.SUM("avg_bet_amount").As("avg_bet_amount"),
				g.SUM("avg_valid_bet_amount").As("avg_valid_bet_amount"),
				g.SUM("profit_rate").As("profit_rate"),
				g.SUM("avg_company_net_amount").As("avg_company_net_amount")).Where(ex).ToSQL()

			err = meta.MerchantDB.Get(&data.Agg, aggQuery)
			if err != nil {
				return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
			}
			cna, _ := decimal.NewFromString(data.Agg.CompanyNetAmount)
			pe, _ := decimal.NewFromString(data.Agg.Presettle)
			ba, _ := decimal.NewFromString(data.Agg.ValidBetAmount)
			if ba.Cmp(decimal.Zero) != 0 {
				data.Agg.ProfitRate = (cna.Add(pe)).Div(ba).StringFixed(4)
			}
		}

		data.D = reportGameFormat(data.D)
		return data, nil
	} else {
		return data, nil
	}

}

func BusinessPlatformReport(page, pageSize int, sStartTime, sEndTime, businessId string) (platformReportData, error) {

	var data platformReportData
	var startTime int64
	if len(sStartTime) > 0 {
		t, err := helper.TimeToLoc(sStartTime, loc) // 秒级时间戳
		if err != nil {
			return data, err
		}
		startTime = t
	}
	var endTime int64
	if len(sEndTime) > 0 {
		t, err := helper.TimeToLoc(sEndTime, loc) // 秒级时间戳
		if err != nil {
			return data, err
		}
		endTime = t
	}
	uids := make([]string, 0)
	members, err := MemberFindByBusinessId(businessId)
	if err != nil {
		return data, err
	}
	if len(members) > 0 {
		for _, val := range members {
			uids = append(uids, val.Uid)
		}
	}
	idArray := StringMontageComma(uids)

	if idArray != "" {
		platformReportJob(startTime, endTime, idArray)
		if err != nil {
			return data, err
		}

		ex := g.Ex{
			"report_time": g.Op{"between": exp.NewRangeVal(startTime, endTime)},
		}
		ex["uids"] = idArray
		t := dialect.From("tbl_report_platform")
		if page >= 1 {
			query, _, _ := t.Select(g.COUNT(1)).Where(ex).ToSQL()

			err := meta.MerchantDB.Get(&data.T, query)
			if err != nil {
				return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
			}

			if data.T == 0 {
				return data, nil
			}
		}

		offset := (uint(page) - 1) * uint(pageSize)
		query, _, _ := t.Select(colsReportPlatform...).Where(ex).Offset(offset).Limit(uint(pageSize)).Order(g.C("report_time").Desc()).ToSQL()

		err = meta.MerchantDB.Select(&data.D, query)
		if err != nil && err != sql.ErrNoRows {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		}

		return data, nil
	} else {
		return data, nil
	}

}

func BusinessPlatformOverview(sStartTime, sEndTime, businessId string) (tblReportPlatform, error) {

	var (
		startTime int64
		data      = tblReportPlatform{}
		sqlData   = reportPlatformSqlNull{}
	)
	if len(sStartTime) > 0 {
		t, err := helper.TimeToLoc(sStartTime, loc) // 秒级时间戳
		if err != nil {
			return data, err
		}
		startTime = t
	}
	var endTime int64
	if len(sEndTime) > 0 {
		t, err := helper.TimeToLoc(sEndTime, loc) // 秒级时间戳
		if err != nil {
			return data, err
		}
		endTime = t
	}
	uids := make([]string, 0)
	members, err := MemberFindByBusinessId(businessId)
	if err != nil {
		return data, err
	}
	if len(members) > 0 {
		for _, val := range members {
			uids = append(uids, val.Uid)
		}
	}
	idArray := StringMontageComma(uids)

	if idArray != "" {
		platformReportJob(startTime, endTime, idArray)
		if err != nil {
			return data, err
		}
		ex := g.Ex{
			"report_time": g.Op{"between": exp.NewRangeVal(startTime, endTime)},
		}

		ex["uids"] = idArray
		query, _, _ := dialect.From("tbl_report_platform").Select(g.C("uids"),
			g.SUM("regist_count").As("regist_count"),
			g.SUM("active_count").As("active_count"),
			g.SUM("efficient_active_count").As("efficient_active_count"),
			g.SUM("first_deposit_count").As("first_deposit_count"),
			g.SUM("second_deposit_count").As("second_deposit_count"),
			g.SUM("third_deposit_count").As("third_deposit_count"),
			g.SUM("deposit_count").As("deposit_count"),
			g.SUM("withdrawal_count").As("withdrawal_count"),
			g.SUM("conversion_rate").As("conversion_rate"),
			g.SUM("first_deposit_amount").As("first_deposit_amount"),
			g.SUM("second_deposit_amount").As("second_deposit_amount"),
			g.SUM("third_deposit_amount").As("third_deposit_amount"),
			g.SUM("avg_first_deposit_amount").As("avg_first_deposit_amount"),
			g.SUM("deposit_mem_count").As("deposit_mem_count"),
			g.SUM("withdrawal_mem_count").As("withdrawal_mem_count"),
			g.SUM("deposit_amount").As("deposit_amount"),
			g.SUM("withdrawal_amount").As("withdrawal_amount"),
			g.SUM("deposit_withdrawal_sub").As("deposit_withdrawal_sub"),
			g.SUM("deposit_withdrawal_rate").As("deposit_withdrawal_rate"),
			g.SUM("bet_mem_count").As("bet_mem_count"),
			g.SUM("bet_num_count").As("bet_num_count"),
			g.SUM("bet_amount").As("bet_amount"),
			g.SUM("valid_bet_amount").As("valid_bet_amount"),
			g.SUM("company_net_amount").As("company_net_amount"),
			g.SUM("avg_company_net_amount").As("avg_company_net_amount"),
			g.SUM("deposit_withdrawal_rate").As("deposit_withdrawal_rate"),
			g.SUM("profit_amount").As("profit_amount"),
			g.SUM("presettle").As("presettle"),
			g.SUM("company_revenue").As("company_revenue")).Where(ex).ToSQL()

		err = meta.MerchantDB.Get(&sqlData, query)
		if err != nil {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		}
		data = tblReportPlatform{
			Id:                    sqlData.Id,
			Uids:                  sqlData.Uids,
			ReportTime:            sqlData.ReportTime,
			ReportType:            sqlData.ReportType,
			ReportMonth:           sqlData.ReportMonth,
			RegistCount:           sqlData.RegistCount.Int64,
			ActiveCount:           sqlData.ActiveCount.Int64,
			EfficientActiveCount:  sqlData.EfficientActiveCount.Int64,
			FirstDepositCount:     sqlData.FirstDepositCount.Int64,
			SecondDepositCount:    sqlData.SecondDepositCount.Int64,
			ThirdDepositCount:     sqlData.ThirdDepositCount.Int64,
			DepositCount:          sqlData.DepositCount.Int64,
			WithdrawalCount:       sqlData.WithdrawalCount.Int64,
			ConversionRate:        sqlData.ConversionRate.Float64,
			FirstDepositAmount:    sqlData.FirstDepositAmount.Float64,
			SecondDepositAmount:   sqlData.SecondDepositAmount.Float64,
			ThirdDepositAmount:    sqlData.ThirdDepositAmount.Float64,
			AvgFirstDepositAmount: sqlData.AvgFirstDepositAmount.Float64,
			DepositMemCount:       sqlData.DepositMemCount.Int64,
			WithdrawalMemCount:    sqlData.WithdrawalMemCount.Int64,
			DepositAmount:         sqlData.DepositAmount.Float64,
			WithdrawalAmount:      sqlData.WithdrawalAmount.Float64,
			DepositWithdrawalSub:  sqlData.DepositWithdrawalSub.Float64,
			DepositWithdrawalRate: sqlData.DepositWithdrawalRate.Float64,
			BetMemCount:           sqlData.BetMemCount.Int64,
			BetNumCount:           sqlData.BetNumCount.Int64,
			BetAmount:             sqlData.BetAmount.Float64,
			ValidBetAmount:        sqlData.ValidBetAmount.Float64,
			CompanyNetAmount:      sqlData.CompanyNetAmount.Float64,
			AvgCompanyNetAmount:   sqlData.AvgCompanyNetAmount.Float64,
			ProfitAmount:          sqlData.ProfitAmount.Float64,
			Presettle:             sqlData.Presettle.Float64,
			CompanyRevenue:        sqlData.CompanyRevenue.Float64,
		}
		return data, nil
	} else {
		return data, nil
	}
}

func gameReportDay(startTime, endTime int64, idArray string) {

	var (
		settleList []TBetReport //游戏报表-结算时间-日报
		//apiSettleList []TBetReport //游戏报表-场馆结算时间-日报
	)

	query := fmt.Sprintf(`select  platform_id,COUNT( row_id ) as bet_count, count(distinct uid ) as mem_count, 
SUM(bet_amount) as bet_amount,SUM(rebate_amount) as rebate_amount,
SUM(valid_bet_amount) as valid_bet_amount, SUM( if ( presettle = 0, 0.0000 - net_amount, 0.0000 )) as company_net_amount, 
SUM( if ( presettle = 1, 0.0000 - net_amount, 0.0000 )) as presettle,
0.0 as profit_rate from tbl_game_record where ( flag = 1) 
and bet_time >= %d  and bet_time < %d and tester in(1,3) and uid in(%s) group by  api_type`, startTime*1000, endTime*1000, idArray)

	err := meta.MerchantDB.Select(&settleList, query)
	if err != nil {
		pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		return
	}

	for i, v := range settleList {
		v.ReportTime = startTime
		v.ReportType = 2
		v.Uids = idArray
		if v.MemCount > 0 {
			v.AvgBetAmount, _ = decimal.NewFromFloat(v.BetAmount).Div(decimal.NewFromInt(v.MemCount)).Float64()
			v.AvgValidBetAmount, _ = decimal.NewFromFloat(v.ValidBetAmount).Div(decimal.NewFromInt(v.MemCount)).Float64()
			v.AvgCompanyNetAmount, _ = decimal.Zero.Sub(decimal.NewFromFloat(v.CompanyNetAmount)).Div(decimal.NewFromInt(v.MemCount)).Float64()
		}
		if v.ValidBetAmount > 0 {
			v.ProfitRate, _ = (decimal.NewFromFloat(v.CompanyNetAmount)).Div(decimal.NewFromFloat(v.ValidBetAmount)).Float64()
		}
		v.Id = v.Prefix + strconv.FormatInt(v.ApiType, 10) + strconv.FormatInt(v.ReportTime, 10) + strconv.FormatInt(v.ReportType, 10)
		settleList[i] = v
	}
	ls := len(settleList)
	ps := 300
	if ls > 0 {
		p := ls / ps
		l := ls % ps
		for x := 0; x < p; x++ {
			offset := x * ps
			updateBet(settleList[offset : offset+ps])
		}

		if l > 0 {
			updateBet(settleList[p*ps:])
		}
	}
}

// updateBet
// @Description: 游戏报表 越南投注时间 更新
// @param list
func updateBet(data []TBetReport) {

	ids := ""
	for _, v := range data {
		ids += ","
		ids += "'" + v.Id + "'"
	}

	tx, err := meta.MerchantDB.Begin()
	if err != nil {
		pushLog(err, "数据库错误")
		return
	}

	query := fmt.Sprintf("delete from tbl_report_game where id in (%s)", strings.TrimPrefix(ids, ","))

	_, err = tx.Exec(query)
	if err != nil {
		_ = tx.Rollback()
		pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		return
	}

	query, _, _ = dialect.From("tbl_report_game").Insert().Rows(data).ToSQL()

	_, err = tx.Exec(query)
	if err != nil {
		_ = tx.Rollback()
		pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		return
	}

	_ = tx.Commit()
}

// 将string数组按逗号拼接成字符串
func StringMontageComma(data []string) string {
	var value string
	for i, val := range data {
		value += val
		if i != len(data)-1 {
			value += ","
		}
	}
	return value
}

func platformReportJob(startTime, endTime int64, idArray string) {

	var (
		registerPList          sql.NullInt64
		depositPList           TDepositsRecord
		withdrawPList          TWithdrawRecord
		settlePList            TGameRecord
		depositCountPList      []TDepositInfo
		betMemlist             []TActiveData
		depositMemlist         []TActiveData
		activeNumPMap          = map[string]map[string]int{}
		efficientActiveNumPMap = map[string]map[string]int{}
		firstDPMap             = map[string]TDepositInfo{}
	)

	sql := fmt.Sprintf(` and uid in(%s) `, idArray)
	timeNow := time.Unix(startTime, 0)                    //2017-08-30 16:19:19 +0800 CST
	startTimeStr := timeNow.Format("2006-01-02 15:04:05") //2015-06-15 08:52:32

	sqlTester := " and tester in(1,3)"
	//注册数
	query := fmt.Sprintf(`SELECT  count( uid ) regist_count FROM tbl_member_base  where 
created_at >= %d and created_at < %d %s %s`, startTime, endTime, sqlTester, sql)
	err := meta.MerchantDB.Get(&registerPList, query)
	if err != nil {
		pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		return
	}

	//存人数 存金额
	query = fmt.Sprintf(`SELECT 
COUNT(DISTINCT uid) AS deposit_num,count(id) as deposit_count, sum( amount ) AS deposit_amount FROM tbl_deposit WHERE state = 362 
and confirm_at >= %d and confirm_at<%d %s %s`, startTime, endTime, sqlTester, sql)
	err = meta.MerchantDB.Get(&depositPList, query)
	if err != nil {
		pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		return
	}

	//提现人数 提现金额
	query = fmt.Sprintf(`SELECT 
COUNT(DISTINCT uid) AS withdraw_num, sum( amount ) AS withdraw_amount,count(id) as withdraw_count FROM tbl_withdraw WHERE state = 374 
and withdraw_at >= %d and withdraw_at<%d %s %s`, startTime, endTime, sqlTester, sql)
	err = meta.MerchantDB.Get(&withdrawPList, query)
	if err != nil {
		pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		return
	}

	query = fmt.Sprintf(`SELECT COUNT(DISTINCT uid) AS bet_mem_count,count(1) as bet_num_count, sum( bet_amount ) AS bet_amount, 
sum( valid_bet_amount ) AS valid_bet_amount, sum( IF ( presettle = 0, 0.0000- net_amount, 0.0000 )) net_amount, 
sum( IF ( presettle = 1, 0.0000- net_amount, 0.0000 )) presettle, count(distinct uid) as bet_mem_count FROM tbl_game_record WHERE flag < 2
and bet_time >= %d and bet_time <%d %s %s`, startTime*1000, endTime*1000, sqlTester, sql)
	err = meta.MerchantDB.Get(&settlePList, query)
	if err != nil {
		pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		return
	}

	query = fmt.Sprintf(`select sum(deposit_amount) as deposit_amount,count(distinct uid) as deposit_count,flags from tbl_member_deposit_info 
	where deposit_at >= %d and deposit_at < %d and flags >0 and flags < 4 %s group by flags`, startTime, endTime, sql)
	err = meta.MerchantDB.Select(&depositCountPList, query)
	if err != nil {
		pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		return
	}

	//活跃人数
	query = fmt.Sprintf(`SELECT uid, sum( amount ) AS deposit_amount, 0 AS bet_amount FROM                                                                     
WHERE state = 362 and amount>0 and confirm_at >= %d and confirm_at < %d %s %s GROUP BY  uid`, startTime, endTime, sqlTester, sql)
	err = meta.MerchantDB.Select(&depositMemlist, query)
	if err != nil {
		pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		return
	}
	query = fmt.Sprintf(`SELECT uid, 0 deposit_amount, sum( bet_amount ) bet_amount FROM tbl_game_record 
WHERE flag < 2 and bet_amount>0 and bet_time >=%d and bet_time <%d %s %s GROUP BY uid`, startTime*1000, endTime*1000+999, sqlTester, sql)
	err = meta.MerchantDB.Select(&betMemlist, query)
	if err != nil {
		pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		return
	}
	for _, v := range betMemlist {
		key := startTimeStr
		_, ok := activeNumPMap[key]
		if ok {
			_, ok2 := activeNumPMap[key][v.Uid]
			if !ok2 {
				activeNumPMap[key][v.Uid] = 1
			}
		} else {
			uidMap := map[string]int{}
			uidMap[v.Uid] = 1
			activeNumPMap[key] = uidMap
		}
		if v.BetAmount > 0 {
			_, ok := efficientActiveNumPMap[key]
			if ok {
				_, ok2 := efficientActiveNumPMap[key][v.Uid]
				if !ok2 {
					efficientActiveNumPMap[key][v.Uid] = 1
				}
			} else {
				uidMap := map[string]int{}
				uidMap[v.Uid] = 1
				efficientActiveNumPMap[key] = uidMap
			}
		}
	}
	for _, v := range depositMemlist {
		key := startTimeStr
		_, ok := activeNumPMap[key]
		if ok {
			_, ok2 := activeNumPMap[key][v.Uid]
			if !ok2 {
				activeNumPMap[key][v.Uid] = 1
			}
		} else {
			uidMap := map[string]int{}
			uidMap[v.Uid] = 1
			activeNumPMap[key] = uidMap
		}
		if v.DepositAmount > 0 {
			_, ok := efficientActiveNumPMap[key]
			if ok {
				_, ok2 := efficientActiveNumPMap[key][v.Uid]
				if !ok2 {
					efficientActiveNumPMap[key][v.Uid] = 1
				}
			} else {
				uidMap := map[string]int{}
				uidMap[v.Uid] = 1
				efficientActiveNumPMap[key] = uidMap
			}
		}
	}

	for _, v := range depositCountPList {
		v.ReportTime = startTimeStr
		key := fmt.Sprintf(`%s|%d`, startTimeStr, v.Flags)
		firstDPMap[key] = v
	}

	//更新平台报表数据

	k := startTimeStr
	obj := tblReportPlatform{
		Id:                   k,
		Uids:                 idArray,
		ReportTime:           startTime,
		ReportMonth:          helper.MonthTST(startTime, loc).Unix(),
		BetMemCount:          settlePList.BetMemCount.Int64,
		BetNumCount:          settlePList.BetNumCount.Int64,
		Presettle:            settlePList.Presettle.Float64,
		ValidBetAmount:       settlePList.ValidBetAmount.Float64,
		EfficientActiveCount: int64(len(efficientActiveNumPMap[k])),
		BetAmount:            settlePList.BetAmount.Float64,
		ProfitAmount:         settlePList.BetAmount.Float64,
		CompanyNetAmount:     settlePList.NetAmount.Float64,
		RegistCount:          registerPList.Int64,
		ActiveCount:          int64(len(activeNumPMap[k])),
		DepositAmount:        depositPList.DepositAmount.Float64,
		DepositCount:         depositPList.DepositCount.Int64,
		DepositMemCount:      depositPList.DepositNum.Int64,
		WithdrawalMemCount:   withdrawPList.WithdrawNum.Int64,
		WithdrawalAmount:     withdrawPList.WithdrawAmount.Float64,
		WithdrawalCount:      withdrawPList.WithdrawCount.Int64,
		FirstDepositCount:    firstDPMap[startTimeStr+"|1"].DepositCount,
		SecondDepositCount:   firstDPMap[startTimeStr+"|2"].DepositCount,
		ThirdDepositCount:    firstDPMap[startTimeStr+"|3"].DepositCount,
	}

	obj.DepositWithdrawalSub, _ = decimal.NewFromFloat(depositPList.DepositAmount.Float64).Sub(decimal.NewFromFloat(withdrawPList.WithdrawAmount.Float64)).Truncate(8).Float64()
	if depositPList.DepositAmount.Float64 != 0 {
		obj.DepositWithdrawalRate, _ = decimal.NewFromFloat(withdrawPList.WithdrawAmount.Float64).Div(decimal.NewFromFloat(depositPList.DepositAmount.Float64)).Truncate(8).Float64()
	}
	obj.CompanyRevenue, _ = decimal.NewFromFloat(settlePList.NetAmount.Float64).Add(decimal.NewFromFloat(settlePList.Presettle.Float64)).Truncate(8).Float64()
	if obj.ValidBetAmount != 0 {
		obj.ProfitAmount, _ = decimal.NewFromFloat(settlePList.NetAmount.Float64).Add(decimal.NewFromFloat(settlePList.Presettle.Float64)).Truncate(8).Div(
			decimal.NewFromFloat(settlePList.ValidBetAmount.Float64)).Mul(decimal.NewFromInt(100)).Truncate(8).Float64()
	}
	//转化率
	if obj.RegistCount != 0 {
		obj.ConversionRate, _ = decimal.NewFromInt(obj.FirstDepositCount).Div(decimal.NewFromInt(obj.RegistCount)).Truncate(8).Float64()
	} else {
		obj.ConversionRate = 0
	}
	obj.FirstDepositAmount = firstDPMap[startTimeStr+"|1"].DepositAmount
	obj.SecondDepositAmount = firstDPMap[startTimeStr+"|2"].DepositAmount
	obj.ThirdDepositAmount = firstDPMap[startTimeStr+"|3"].DepositAmount
	//平均首存比
	if obj.FirstDepositCount != 0 {
		obj.AvgFirstDepositAmount, _ = decimal.NewFromFloat(obj.FirstDepositAmount).Div(decimal.NewFromInt(obj.FirstDepositCount)).Truncate(8).Float64()
	} else {
		obj.AvgFirstDepositAmount = 0
	}
	//公司平均输赢
	if obj.BetMemCount > 0 {
		obj.AvgCompanyNetAmount, _ = decimal.NewFromFloat(obj.CompanyNetAmount).Div(decimal.NewFromInt(obj.BetMemCount)).Truncate(8).Float64()
	} else {
		obj.AvgCompanyNetAmount = 0
	}

	obj.ReportType = 2

	updatePlatform(obj)
}

func updatePlatform(v tblReportPlatform) {

	v.Id = v.Id + "|" + strconv.Itoa(v.ReportType)

	tx, err := meta.MerchantDB.Begin()
	if err != nil {
		pushLog(fmt.Errorf("%s", err.Error()), "数据库错误")
		return
	}

	query := fmt.Sprintf("delete from tbl_report_platform where id = '%s'", v.Id)

	_, err = tx.Exec(query)
	if err != nil {
		_ = tx.Rollback()
		pushLog(fmt.Errorf("%s", err.Error()), "数据库错误")
		return
	}

	query, _, _ = dialect.From("tbl_report_platform").Insert().Rows(v).ToSQL()

	_, err = tx.Exec(query)
	if err != nil {
		_ = tx.Rollback()
		pushLog(fmt.Errorf("%s", err.Error()), "数据库错误")
		return
	}

	_ = tx.Commit()
}
